package top.lyjwn.ajui.util;

import android.content.Context;
import android.util.Log;
import android.view.View;

import com.xuexiang.xui.widget.picker.wheelview.WheelView;
import com.xuexiang.xui.widget.picker.widget.OptionsPickerView;
import com.xuexiang.xui.widget.picker.widget.TimePickerView;
import com.xuexiang.xui.widget.picker.widget.builder.OptionsPickerBuilder;
import com.xuexiang.xui.widget.picker.widget.builder.TimePickerBuilder;
import com.xuexiang.xui.widget.picker.widget.configure.TimePickerType;
import com.xuexiang.xui.widget.picker.widget.listener.OnOptionsSelectListener;
import com.xuexiang.xui.widget.picker.widget.listener.OnTimeSelectChangeListener;
import com.xuexiang.xui.widget.picker.widget.listener.OnTimeSelectListener;
import com.xuexiang.xutil.data.DateUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;

public class DateUtil {

    private final static List<Year> years = getYears();


    /**
     * 由出生日期获取年龄
     *
     * @param birthDay
     * @return
     * @throws Exception
     */
    public static int getAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) {
            Log.v("计算年龄错误",
                    "这个出生日期在未来");
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);

        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) age--;
            } else {
                age--;
            }
        }
        return age;
    }

    /**
     * @param date
     * @param day  想要获取的日期与传入日期的差值 比如想要获取传入日期前四天的日期 day=-4即可
     * @return
     */
    public static Date getSomeDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 日期差天数、小时、分钟、秒数组
     *
     * @param startDate
     * @param endDate
     * @return long[1, 2, 3, 4] = {day, hour, min, sec}
     */
    public static long[] getDisTime(Date startDate, Date endDate) {
        long timesDis = Math.abs(startDate.getTime() - endDate.getTime());
        long day = timesDis / (1000 * 60 * 60 * 24);
        long hour = timesDis / (1000 * 60 * 60) - day * 24;
        long min = timesDis / (1000 * 60) - day * 24 * 60 - hour * 60;
        long sec = timesDis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60;
        return new long[]{day, hour, min, sec};
    }

    /**
     * 日期差天数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static Long getDisDay(Date startDate, Date endDate) {
        long[] dis = getDisTime(startDate, endDate);
        long day = dis[0];
        if (dis[1] > 0 || dis[2] > 0 || dis[3] > 0) {
            day += 1;
        }
        return day;
    }

    /**
     * 日期差文字描述
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static String getDisTimeStr(Date startDate, Date endDate) {
        long[] dis = getDisTime(startDate, endDate);
        return new StringBuilder().append(dis[0]).append("天").append(dis[1]).append("小时").append(dis[2]).append("分钟")
                .append(dis[3]).append("秒").toString();
    }

    /**
     * 获取中文说明的整小时数//时间（上午10:00）
     *
     * @param time
     * @return
     */
    public static String getChinaHHmm(long time) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        SimpleDateFormat hhSdf = new SimpleDateFormat("HH");
        Date date = new Date(time);
        String format = simpleDateFormat.format(date);
        String hhformat = hhSdf.format(date);
        Integer integer = Integer.valueOf(hhformat);

        if (integer > 12) {
            return "下午 " + format;
        } else {
            return "上午 " + format;
        }
    }

    /**
     * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
     *
     * @param strDate
     * @return
     */
    public static Date stringToTime(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
     *
     * @param strDate
     * @return
     */
    public static Date stringToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * 日期选择
     *
     * @param context
     * @param date
     */
    public static void selectDate(Context context, Date date, OnSelectListener listener) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        TimePickerView mTimePickerDialog = new TimePickerBuilder(context, new OnTimeSelectListener() {
            @Override
            public void onTimeSelected(Date date, View v) {
                if (listener != null) {
                    listener.onSelect(date.getTime(), DateUtils.date2String(date, DateUtils.yyyyMMdd.get()));
                }
            }
        })
                .setTimeSelectChangeListener(new OnTimeSelectChangeListener() {
                    @Override
                    public void onTimeSelectChanged(Date date) {
                        Log.i("pvTime", "onTimeSelectChanged");
                    }
                })
                .setType(TimePickerType.DEFAULT)
                .setTitleText("日期选择")
                .isDialog(false)
                .setContentTextSize(22)
                .setLineSpacingMultiplier(2f)
                .setOutSideCancelable(true)
                .setDate(calendar)
                .build();
        mTimePickerDialog.show();
    }

    /**
     * 日期选择
     *
     * @param context
     */
    public static void selectDate(Context context, OnSelectListener listener) {
        selectDate(context, new Date(), listener);
    }

    /**
     * 年份选择
     *
     * @param context
     */
    public static void selectYear(Context context, OptionsYear listener) {
        OptionsPickerView<Year> pvOptions = new OptionsPickerBuilder(context, new OnOptionsSelectListener() {
            @Override
            public boolean onOptionsSelect(View view, int options1, int options2, int options3) {
                Year year = years.get(options1);
                listener.onOptionsSelect(year);
                return false;
            }
        }).build();
        pvOptions.setPicker(years);
        pvOptions.setSelectOptions(50);
        pvOptions.setTitleText("选择年份");
        pvOptions.show();
    }


    /**
     * 日期选择
     *
     * @param context
     * @param date
     */
    public static void selectDate(Context context, Date date, OnSelectListener listener,Calendar startDate, Calendar endDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        TimePickerView mTimePickerDialog = new TimePickerBuilder(context, new OnTimeSelectListener() {
            @Override
            public void onTimeSelected(Date date, View v) {
                if (listener != null) {
                    listener.onSelect(date.getTime(), DateUtils.date2String(date, DateUtils.yyyyMMdd.get()));
                }
            }
        })
                .setTimeSelectChangeListener(new OnTimeSelectChangeListener() {
                    @Override
                    public void onTimeSelectChanged(Date date) {
                        Log.i("pvTime", "onTimeSelectChanged");
                    }
                })
                .setType(TimePickerType.DEFAULT)
                .setTitleText("日期选择")
                .isDialog(false)
                .setContentTextSize(22)
                .setLineSpacingMultiplier(2f)
                .setOutSideCancelable(true)
                .setDate(calendar)
                .setRangDate( startDate,  endDate)
                .build();
        mTimePickerDialog.show();
    }
    /**
     * 日期选择
     * @param context
     * @param listener
     * @param startDate
     * @param endDate
     */
    public static void selectDate(Context context, OnSelectListener listener, Calendar startDate, Calendar endDate) {
        selectDate(context, new Date(), listener,startDate,endDate);
    }


    /**
     * 分段选择时间点
     *
     * @param context
     */
    public static void selectTimingSection(Context context, OnSelectListener listener, @TimeFrame int... timeFrame) {
        String[][] mTimeOption1;
        List<String> optionList = new ArrayList<>();
        mTimeOption1 = new String[timeFrame.length][];
        for (int i = 0; i < 5 && i < timeFrame.length; i++) {
            switch (timeFrame[i]) {
                case 0:
                    mTimeOption1[i] = getTimePeriod(0, 6, 15);
                    optionList.add("凌晨");
                    break;
                case 1:
                    mTimeOption1[i] = getTimePeriod(6, 6, 15);
                    optionList.add("上午");
                    break;
                case 2:
                    mTimeOption1[i] = getTimePeriod(12, 1, 15);
                    optionList.add("中午");
                    break;
                case 3:
                    mTimeOption1[i] = getTimePeriod(13, 5, 15);
                    optionList.add("下午");
                    break;
                case 4:
                    mTimeOption1[i] = getTimePeriod(6, 6, 15);
                    optionList.add("晚上");
                    break;
            }
        }
        String[] option = optionList.toArray(new String[optionList.size()]);

        //8点
        int defaultOption = 2 * 60 / 15;
        OptionsPickerView pvOptions = new OptionsPickerBuilder(context, new OnOptionsSelectListener() {
            @Override
            public boolean onOptionsSelect(View v, int options1, int options2, int options3) {
                if (listener != null) {
                    Date date = DateUtils.string2Date(mTimeOption1[options1][options2], DateUtils.HHmm.get());
                    listener.onSelect(date.getTime(), mTimeOption1[options1][options2]);
                }
                return false;
            }
        })
                .setTitleText("时间点选择")
                .isRestoreItem(true)
                .setSelectOptions(1, defaultOption)
                .setContentTextSize(22)
                .setLineSpacingMultiplier(2.2f)
                .setDividerType(WheelView.DividerType.WRAP)
                .setOutSideCancelable(true)
                .build();
        pvOptions.setPicker(option, mTimeOption1);
        pvOptions.show();
    }



    /**
     * 时段选择
     *
     * @param context
     */
    public static void selectTimeFrame(Context context, OnSelectListener listener) {
            String[] mTimeOption = getTimePeriod(15);

        //8点
        int defaultOption = 8 * 60 / 15;

        OptionsPickerView pvOptions = new OptionsPickerBuilder(context, new OnOptionsSelectListener() {
            @Override
            public boolean onOptionsSelect(View v, int options1, int options2, int options3) {
                if (options1 > options2) {
                    ToastUtil.normal(context, "结束时间不能早于开始时间");
                    //返回为true意为拦截，选择框不消失。
                    return true;
                } else {
                    if (listener != null) {
                        Date date = DateUtils.string2Date(mTimeOption[options1], DateUtils.HHmm.get());
                        listener.onSelect(date.getTime(), mTimeOption[options1] + "~" + mTimeOption[options2]);
                    }
                    return false;
                }
            }
        })
                .setTitleText("时间段选择")
                .setSelectOptions(defaultOption, defaultOption)
                .build();
        pvOptions.setNPicker(mTimeOption, mTimeOption);
        pvOptions.show();
    }


    /**
     * 时间选择回调
     */
    public interface OnSelectListener {
        void onSelect(long time, String format);
    }

    /**
     * 获取时间段
     *
     * @param interval 时间间隔（分钟）
     * @return
     */
    public static String[] getTimePeriod(int startHour, int totalHour, int interval) {
        String[] time = new String[totalHour * 60 / interval];
        int point, hour, min;
        for (int i = 0; i < time.length; i++) {
            point = i * interval + startHour * 60;
            hour = point / 60;
            min = point - hour * 60;
            time[i] = (hour < 9 ? "0" + hour : "" + hour) + ":" + (min < 9 ? "0" + min : "" + min);
        }
        return time;
    }

    /**
     * 获取时间段
     *
     * @param interval 时间间隔（分钟）
     * @return
     */
    public static String[] getTimePeriod(int totalHour, int interval) {
        String[] time = new String[totalHour * 60 / interval];
        int point, hour, min;
        for (int i = 0; i < time.length; i++) {
            point = i * interval;
            hour = point / 60;
            min = point - hour * 60;
            time[i] = (hour < 9 ? "0" + hour : "" + hour) + ":" + (min < 9 ? "0" + min : "" + min);
        }
        return time;
    }

    /**
     * 获取时间段
     *
     * @param interval 时间间隔（分钟）
     * @return
     */
    public static String[] getTimePeriod(int interval) {
        return getTimePeriod(24, interval);
    }


    /**
     * 凌晨
     */
    public static final int WEE_HOURS = 0;
    /**
     * 上午
     */
    public static final int MORNING = 1;
    /**
     * 中午
     */
    public static final int NOON = 2;
    /**
     * 下午
     */
    public static final int AFTERNOON = 3;
    /**
     * 晚上
     */
    public static final int NIGHT = 4;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value = {WEE_HOURS, MORNING, NOON, AFTERNOON, NIGHT})
    public @interface TimeFrame {

    }


    private static List<Year> getYears(){
        SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
        String yyyyStr = yyyy.format(new Date());
        Integer yyyyInt = Integer.valueOf(yyyyStr);
        List<Year> years = new ArrayList<>();
        for (int i = 50;i>0;i--){
            years.add(new Year(yyyyInt - i,String.valueOf(yyyyInt - i)));
        }
        for (int i = 0;i<50 ; i++){
            years.add(new Year(yyyyInt + i,String.valueOf(yyyyInt + i)));
        }
        return years;

    }

    public static class Year{
        private int number;
        private String character;

        public Year() {
        }

        public Year(int number, String character) {
            this.number = number;
            this.character = character;
        }

        public int getNumber() {
            return number;
        }

        public void setNumber(int number) {
            this.number = number;
        }

        public String getCharacter() {
            return character;
        }

        public void setCharacter(String character) {
            this.character = character;
        }

        @NonNull
        @Override
        public String toString() {
            return this.character;
        }
    }

    public interface OptionsYear{
       void onOptionsSelect(Year year);
    }




}
